#include "ThreadMovimiento.h"
#include "ChequeadorColisiones.h"
#include "Elemento.h"

int thread_func_mov(void *unused)
{	
	Escenario *esc=(Escenario*)unused;
	bool choco, reacomodo = true;
	Pelota* pelotaDesde;//Pelota desde donde se reacomoda luego de eliminar
	
	ChequeadorColisiones* checkColisiones= new ChequeadorColisiones();
	checkColisiones->setTamanioPantalla(esc->GetGeneral()->GetResolucion(),esc->GetGeneral()->GetResolucionAlto());
	checkColisiones->addSumidero(esc->getSumideros());
	checkColisiones->addDispersor(esc->getListaDispersores());
	checkColisiones->addCarril(esc->getCarril());
	checkColisiones->setEscenario(esc);
	checkColisiones->setBonus(NULL);
	
	TipoChoque* tipoChoque;
	Carril* carril=esc->getCarril();

	GeneradorBonus* gBonus=new GeneradorBonus(esc);
	Pelota* pelotaEnVuelo;
	Pelota* pelotaChocada;
	string tBonus="";
	double anguloRebote=0;

	int puntosAcumulados=0;

	while ( esc->finDeJuego == 0 ) 
    {
		//ejecuto el generador de bonus
		gBonus->Generar(checkColisiones);

		//Llamar al mover carril
		carril->Mover();

		//Verifico que la primer pelota del carril choque contra el sumidero
		esc->finDeJuego=checkColisiones->verificarCarril();
	
		
		//cout << "Modificando posiciones \n ";
		pelotaEnVuelo = esc->getPelotaEnVuelo();
		if (pelotaEnVuelo!=NULL){
			 tipoChoque = checkColisiones->verificar(pelotaEnVuelo);
			if (tipoChoque->huboColision()){
				if (tipoChoque->chocoCarril()){
				
					//muevo la pelota
					pelotaEnVuelo->setPosX(pelotaEnVuelo->getSiguientePosicion().getPosX());
					pelotaEnVuelo->setPosY(pelotaEnVuelo->getSiguientePosicion().getPosY());
					
					//Aviso al carril que lo chocaron, en que pelota y donde.
					pelotaChocada=(Pelota*)tipoChoque->getElemColisionado();
					carril->Colision(pelotaChocada,pelotaEnVuelo,tipoChoque->izqDeCarril());

					while (reacomodo)
					{
					   if (pelotaEnVuelo != NULL)
					   {
					      pelotaDesde = carril->eliminoPelotas(pelotaEnVuelo);
					      pelotaEnVuelo = NULL;
					   }
					   else{
					      pelotaDesde = carril->eliminoPelotas(pelotaDesde);
					   }

					   if ( pelotaDesde != NULL )
					   {
					      carril->MoverInverso(pelotaDesde);
					      /*pelotaEnVuelo = pelotaDesde;*/
					      //pelotaDesde = NULL; //SR
					   }
					   else 
						   reacomodo =false;
					}
					reacomodo = true;
					esc->setPelotaEnVuelo(NULL);
					pelotaDesde = NULL;

					//veo si se quedo sin pelotas la fuente y activo el primer tramo
					if ( esc->getCarril()->getCantidadPelotas() <= esc->getCarril()->getCantidadPelotasEmitidas() && (esc->getCarril()->GetListaDePelotas().empty() == false))
					{
						esc->getCarril()->estadoFinal();
					}
							
				}else if (tipoChoque->pelotaFueraPantalla()){
				//	cout << "Se fue de la pantalla";
					pelotaEnVuelo=esc->getPelotaEnVuelo();
					free(pelotaEnVuelo);
					esc->setPelotaEnVuelo(NULL);

				}else if (tipoChoque->finDeJuego()){
					cout << "\nPerdiste";
					esc->finDeJuego=1;

				}else if (tipoChoque->chocoBonus()){
					//me fijo que tipo de bonus se choco
					tBonus=tipoChoque->getTipoBonus();
					esc->setBonusEnPantalla(NULL);
					checkColisiones->deleteBonus();
					if (tBonus=="vida"){
						cout << "Choco un bonus de vida";
						esc->setVidas(esc->getVidas()+1);
					}else if (tBonus=="puntos"){
						cout << "Choco un bonus de puntos";
						esc->getCarril()->setPuntosCarril(esc->getCarril()->getPuntosCarril()+300);
					}else if (tBonus=="retroceso"){
						cout << "Choco un bonus de Retroceso";
						carril->BonusRetroceso(BONUSRETROCESO);
					}else if (tBonus=="precision"){
						cout << "Choco un bonus de Precision";
						esc->getSapo()->activarLaser();
					}else if (tBonus=="freno"){
						cout << "Choco un bonus de freno";
						carril->BonusFreno();
					}
				}
				else{

					anguloRebote=tipoChoque->getAnguloRebote();
					pelotaEnVuelo->setAnguloTrayectoria(anguloRebote);

					//Cambio la direccion de la pelota
					pelotaEnVuelo->setPosX(pelotaEnVuelo->getSiguientePosicion().getPosX());
					pelotaEnVuelo->setPosY(pelotaEnVuelo->getSiguientePosicion().getPosY());

					
				}
			}else // En el proximo paso no choca por lo tanto lo muevo.
				{
					pelotaEnVuelo->setPosX(pelotaEnVuelo->getSiguientePosicion().getPosX());
					pelotaEnVuelo->setPosY(pelotaEnVuelo->getSiguientePosicion().getPosY());
				}
		}
		SDL_Delay(10);
		//chequeo si se gano el nivel
		if ((esc->getCarril()->getCantidadPelotasEnCarril()==0) && (esc->getCarril()->getCantidadPelotas()==esc->getCarril()->getCantidadPelotasEmitidas())){
			cout << "\nSe gano el nivel";
			esc->finDeJuego=2;
		}
	}
    //printf("Saliendo del hilo\n");
	free(checkColisiones);
    return(0);
}


ThreadMovimiento::ThreadMovimiento(Escenario *esc)
{
	SDL_Thread *thread;
  	thread = SDL_CreateThread(thread_func_mov, esc);
    if ( thread == NULL ) 
    {
        fprintf(stderr, "No se puede crear el hilo de Movimiento: %s\n",
	        SDL_GetError());
        return;
    }

   
}
